﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StockholmsStad.Data.Interfaces;
using StockholmsStad.Runtime.Serialization.DataContract;

namespace StockholmsStad.Business.Test
{
    /// <summary>
    ///This is a test class for MinisterBusinessTest and is intended
    ///to contain all MinisterBusinessTest Unit Tests
    ///</summary>
    [TestClass()]
    public class MinisterBusinessTest
    {
        private readonly User _user = new User();
        private IDataContext _context;
        private MockRepository _mocks = new MockRepository();

        #region Additional test attributes

        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}

        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            _mocks = new MockRepository();
        }

        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        private MinisterBusiness GetTarget(IAgentFactory agentFactory)
        {
            var target = new MinisterBusiness(_user) {AgentFactory = agentFactory};
            _context = _mocks.DynamicMock<IDataContext>();
            IContextFactory contextFactory = new MockContextFactory(_context);
            //target.ContextFactory = contextFactory;
            return target;
        }

        /// <summary>
        ///A test for IsBookingCodeValid. No code.
        ///</summary>
        [TestMethod()]
        public void IsBookingCodeValidTest()
        {
            var agentFactory = new MockAgentFactory();
            IMinisterAgent ministerAgent = _mocks.StrictMock<IMinisterAgent>();
            agentFactory.MinisterAgent = ministerAgent;
            MinisterBusiness target = GetTarget(agentFactory);
            // Expect
            Expect.Call(ministerAgent.GetMinisterIdByMinisterCode(_context, "TeLeLeDnInGsAnKa")).Return(null);
            // Replay
            _mocks.ReplayAll();
            bool actual = target.IsBookingCodeValid("TeLeLeDnInGsAnKa");
            Assert.AreEqual(false, actual);
            _mocks.VerifyAll();
        }

        /// <summary>
        ///A test for IsBookingCodeValid. Found code.
        ///</summary>
        [TestMethod()]
        public void IsBookingCodeValidTest2()
        {
            var agentFactory = new MockAgentFactory();
            IMinisterAgent ministerAgent = _mocks.StrictMock<IMinisterAgent>();
            agentFactory.MinisterAgent = ministerAgent;
            MinisterBusiness target = GetTarget(agentFactory);
            // Expect
            Expect.Call(ministerAgent.GetMinisterIdByMinisterCode(_context, "TeLeLeDnInGsAnKa")).Return(42);
            // Replay
            _mocks.ReplayAll();
            bool actual = target.IsBookingCodeValid("TeLeLeDnInGsAnKa");
            Assert.AreEqual(true, actual);
            _mocks.VerifyAll();
        }

        [TestMethod()]
        public void AddMinisterTest()
        {
            var agentFactory = new MockAgentFactory();
            IMinisterAgent ministerAgent = _mocks.StrictMock<IMinisterAgent>();
            agentFactory.MinisterAgent = ministerAgent;
            MinisterBusiness target = GetTarget(agentFactory);
            // Object
            Minister minister = new Minister();
            // Expect
            Expect.Call(ministerAgent.AddMinister(_context, minister)).Return(123);
            // Replay
            _mocks.ReplayAll();
            int actual = target.AddMinister(minister);
            Assert.AreEqual(123, actual);
            _mocks.VerifyAll();
        }

        [TestMethod()]
        public void UpdateMinisterTest()
        {
            var agentFactory = new MockAgentFactory();
            IMinisterAgent ministerAgent = _mocks.StrictMock<IMinisterAgent>();
            agentFactory.MinisterAgent = ministerAgent;
            MinisterBusiness target = GetTarget(agentFactory);
            // Object
            Minister minister = new Minister(){MinisterId = 123};
            // Expect
            Expect.Call(() => ministerAgent.UpdateMinister(_context, 123, minister));
            // Replay
            _mocks.ReplayAll();
            target.UpdateMinister(minister);
            _mocks.VerifyAll();
        }

        [TestMethod()]
        public void RemoveMinisterTest()
        {
            var agentFactory = new MockAgentFactory();
            IMinisterAgent ministerAgent = _mocks.StrictMock<IMinisterAgent>();
            agentFactory.MinisterAgent = ministerAgent;
            MinisterBusiness target = GetTarget(agentFactory);
            // Expect
            Expect.Call(() => ministerAgent.RemoveMinister(_context, 123));
            // Replay
            _mocks.ReplayAll();
            target.RemoveMinister(123);
            _mocks.VerifyAll();
        }

        [TestMethod()]
        public void GetMinistersTest()
        {
            var agentFactory = new MockAgentFactory();
            IMinisterAgent ministerAgent = _mocks.StrictMock<IMinisterAgent>();
            agentFactory.MinisterAgent = ministerAgent;
            MinisterBusiness target = GetTarget(agentFactory);
            // Object
            Minister minister = new Minister();
            List<Minister> expected = new List<Minister>() {minister};
            // Expect
            Expect.Call(ministerAgent.GetMinisters(_context)).Return(expected);
            // Replay
            _mocks.ReplayAll();
            List<Minister> actual = target.GetMinisters();
            Assert.AreEqual(expected, actual);
            _mocks.VerifyAll();
        }

        /// <summary>
        ///A test for MinisterBusiness Constructor
        ///</summary>
        [TestMethod()]
        public void MinisterBusinessConstructorTest()
        {
            User user = new User() {};
            MinisterBusiness target = new MinisterBusiness(user);
            Assert.IsNotNull(target);
        }

        /// <summary>
        ///A test for MinisterBusiness Constructor
        ///</summary>
        [TestMethod()]
        public void MiscDateTestTest()
        {
            const string origMessage = "{0:'datum' yyyy-MM-dd}";
            string message = string.Format(origMessage, new DateTime(2008, 1, 2));
            Assert.AreEqual("datum 2008-01-02", message);
            message = string.Format(origMessage, "");
            Assert.AreEqual("", message);
        }
    }
}